import urllib
from validator import validate_snp_name, ValidationError

def lookup_snps(snp_list):

    #NB Som entries has two genenames separated by a comma i.e. X,Y
    #Has to corrected to only one gene-name
    #Precautions has been taken in other scripts, but should be removed, when above is solved.
    efetch_url = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=snp&retmode=text&rettype=chr" # rettype=chr retrieves chromozome info str
    
    snp_list, invalid_snps = check_snp_names(snp_list)
        
    snp_list_str = ",".join(snp_list)
    enc_snp_str = urllib.urlencode({"id":snp_list_str}) 
    wpage = urllib.urlopen(efetch_url, enc_snp_str)
    snp_gene_list = []
    #line_nr = 0
    snp_index = 0
    #num_snps = len(snp_list)
    output_lines = wpage.read().split("\n")
    #print "snp_list", snp_list
    #print "output_lines", output_lines, len(output_lines)
    
    for line in output_lines:
        if not line.strip():
            continue
     #   print "snp_index", snp_index
        snp_data = None
        try :
            gene = line.split()[-9] # the 9th last element is the gene name
            if gene.strip() == "-":
                gene = "EXOGENIC"
                #gene = snp_list[snp_index]                
            chromosome = line.split()[9] # this should be the chromosome number
            snp_data = (snp_list[snp_index], gene, chromosome) # (SNP name, gene, chromosome nr)
            
        except IndexError:
#            snp_data = (snp_list[snp_index], "NA", "NA")
            snp_data = (snp_list[snp_index], gene, chromosome)
        
        snp_gene_list.append(snp_data) 
        
        snp_index += 1
    
    for snp in invalid_snps:
        snp_gene_list.append((snp, "no gene data", -1))
    
    return snp_gene_list
    

def gene_associations(snps, callback=None):
    SNPS_PER_LOOKUP = 50#200 #Is this the block-size of retrivels or just monitoring?
    association_list = []
    for i in xrange(0, len(snps), SNPS_PER_LOOKUP):
        
        sub_list = lookup_snps(snps[i:i+SNPS_PER_LOOKUP])
        if len(snps[i:i+SNPS_PER_LOOKUP]) != len(sub_list):
            print "length error. submitted:", len(snps[i:i+SNPS_PER_LOOKUP]), "returned", len(sub_list)  
            sub_list = handle_snp_gene_mismatch(snps[i:i+SNPS_PER_LOOKUP],sub_list)
            
        association_list.extend(sub_list)
        print "looking up %i to %i : snps %i returned %i" % (i, i+SNPS_PER_LOOKUP, len(snps[i:i+SNPS_PER_LOOKUP]), len(sub_list))
        if callback:
            msg = "%i of %i" % (i, len(snps))
            exit = callback(int(float(i)/len(snps)*100), msg)
            if exit:
                return []
    
    return association_list


def handle_snp_gene_mismatch(snp_list,returned_snp_gene_list):
    print "lookup snp list", snp_list
    print "returned snp gene list", returned_snp_gene_list
    new_snp_gene_list = []
    for snp in snp_list:
        found = 0
        for returned_snp_gene_info in returned_snp_gene_list:
            if snp == returned_snp_gene_info[0]: # index 0 is snp name
                new_snp_gene_list.append(returned_snp_gene_info)
                found = 1
                break            
        
        if not found:
            new_snp_gene_list.append((snp, "Invalid SNPs", "-1"))
    return new_snp_gene_list

def check_snp_names(snp_list):
    validated_snps = []
    invalid_snps = []
    for snp in snp_list:
        try:
            validate_snp_name(snp)
            validated_snps.append(snp)

        except ValidationError, e:
            invalid_snps.append((snp,str(e)))
    return validated_snps, invalid_snps
